/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package optinsa;

import java.util.ArrayList;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author falxa
 */
public class Solution 
{
    private ArrayList<ArrayList<Task>> solution;
    private int dateMax;
    private Problem template;
    
    public Solution(int n, Problem template)
    {
        this.solution = new ArrayList<>();
        for (int i=0; i<n; i++)
            this.solution.add(new ArrayList<Task>());
        this.template = template;
    }
    
    public void addSolution(Task task)
    {
        int resID = task.getRessource().getID();
        /*for (int i=0; i<this.solution.get(resID).size(); i++)
            if (task.getDate() < this.solution.get(resID).get(i).getDate())
            {
                this.solution.get(resID).add(i, task);
                break;
            }*/
        this.solution.get(resID).add(task);
        
        int max = task.getDate()+task.getDuration();
        if (this.dateMax < max) this.dateMax = max;
    }
    
    public void printSolution()
    {
        String s;
        ArrayList<Task> tasks;
        for (int i=0; i<this.solution.size(); i++)
        {
            tasks = this.solution.get(i);
            
            s = "R"+i+": ";
            for (int j=0; j<tasks.size(); j++)
            {
                s += "(J"+tasks.get(j).getJob()+", "+tasks.get(j).getDate()+", "+tasks.get(j).getDuration()+")";
            }
            System.out.println(s);
        }
    }
    
    public int evalSolution()
    {
        boolean end = false;
        int depth = 0;
        int date;
        Job tjob;
        Task t;
        
        while (!end)
        {
            for (int i=0; i<this.solution.size(); i++)
            {
                end = true;
                
                if (depth < this.solution.get(i).size())
                {
                    t = this.solution.get(i).get(depth);
                    tjob = this.template.getJobs().get(t.getJob());
                    
                    date = Math.max(tjob.getDate(), t.getRessource().isFreeIn());
                    t.doTask(date);
                    tjob.setDate(t.getDate() + t.getDuration());
                    if (date > this.dateMax) this.dateMax = date;

                    end = false;
                }
            }
            depth++;
        }
        
        this.template.displayJobs();
        
        return this.dateMax;
    }
    
    public int getDateMax()
    {
        return this.dateMax;
    }
    
    public ArrayList<Solution> genNeighbour()
    {
        ArrayList<Solution> neighbours = new ArrayList<>();
        Solution neighbour = null;
        
        for (int i=0; i<this.solution.size(); i++)
        {
            for (int j=0; j<this.solution.size()-1; j++)
            {
                int s1=j, s2=j+1;
                neighbour = this.clone();
                neighbour.solution.get(0).get(s2).setDate(solution.get(0).get(s1).getDate());
                Collections.swap(neighbour.solution.get(i),s1,s2);
                neighbours.add(neighbour);
            }
        }
        
        return neighbours;
    }
    
    public Solution clone()
    {
        Solution solclone = new Solution(this.solution.size(), this.template.clone());
        for (int i=0; i<this.solution.size(); i++)
        {
            for (int j=0; j<this.solution.get(i).size(); j++)
            {
                int tid = this.solution.get(i).get(j).getID();
                int jid = this.solution.get(i).get(j).getJob();
                Task t = solclone.template.getJobs().get(jid).getTasks().get(tid);
                solclone.addSolution(t);
            }
        }
        return solclone;
    }
}
